<?php

namespace app\common\service\store;


use app\admin\model\live\LiveGoods;
use app\admin\model\order\OrderGoodsInfo;
use app\admin\model\store\Goods;
use app\admin\model\store\GoodsCate;
use app\admin\model\store\GoodsComment;
use app\admin\model\store\GoodsExchange;
use app\admin\model\store\GoodsSku;
use app\admin\model\store\GoodsSpecifica;
use app\common\service\BaseService;
use app\common\service\lib\Cos;
use app\common\service\lib\Es;
use think\facade\Cache;
use think\facade\Event;

class GoodsService extends BaseService
{
    /**
     * Author:Zhongyuan Lu
     * 获取商品列表
     * @param $page
     * @param $limit
     * @param $where
     * @param int $isDelete
     * @return array
     * @throws \think\db\exception\DbException
     */
    public static function getGoodsList($page, $limit, $where, $isDelete = 0)
    {
        $model = new Goods();
        if ($isDelete) {
            $list = $model->onlyTrashed()->order('id desc')->paginate($limit);
        } else {
            $list = $model->where($where)->paginate($limit);
        }

        $list && $list = $list->toArray();

        $data = [
            'code' => 0,
            'msg' => '',
            'count' => $list['total'],
            'data' => $list['data'],
        ];
        return $data;
    }

    /**
     * Author:Zhongyuan Lu
     * 根据skuId获取商品id
     * @param $skuId
     * @return mixed
     */
    public static function getGoodsId($skuId)
    {
        return GoodsSku::where('id',$skuId)->value('goods_id');
    }

    /**
     * Author:Zhongyuan Lu
     * 获取商品图片
     * @param $ids
     * @return array
     */
    public static function getGoodsImages($ids)
    {
        if (is_int($ids)) $where[] = ['id','=',$ids];
        if (is_array($ids)) $where[] = ['id','in',$ids];
        if (is_string($ids) && strpos($ids,',')) {
            $ids = explode(',', $ids);
            $where[] = ['id','in',$ids];
        }
        return Goods::where($where)->column('image');
    }

    /**
     * Author:YangXinPeng
     * 商品spu及sku添加
     * @param $post
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function goodsSave($post)
    {
        if ($post['is_specifica'] == 0) {
            $sku = $post['sku'];
            unset($post['sku'], $post['file'], $post['skuGoods'], $post['attr']);
            try {
                $data = Goods::create($post);
                $sku['goods_id'] = $data->id;
                $sku['virtual_inventory'] = $post['virtual_inventory'];
                GoodsSku::create($sku);
                $info = Goods::find($data->id);
            } catch (\Exception $e) {
                $data = [
                    'code' => 0,
                    'msg' => '添加失败',
                    'data' => []
                ];
                return $data;
            }
        } else {
            $skuGoods = $post['skuGoods'];
            $goodsAttr = $post['attr'];
            unset($post['skuGoods'], $post['sku'], $post['file'], $post['attr']);
            $attr = explode(',', $goodsAttr);
            try {
                $info = Goods::create($post);
                foreach ($skuGoods as $k => &$v) {
                    foreach ($attr as $key => $value) {
                        $v['goods_id'] = $info->id;
                        $v['attr_values'][$value] = $v[$value];
                        unset($v[$value]);
                    }
                    $v['attr_values'] = json_encode($v['attr_values']);
                }
                unset($v);
                $goodsSku = new GoodsSku();
                $goodsSku->insertAll($skuGoods);
            } catch (\Exception $e) {
                $data = [
                    'code' => 0,
                    'msg' => '添加失败',
                    'data' => []
                ];
                return $data;
            }
        }
        //商品添加到es中
        $es = new Es();
        $goods_name = $info->goods_name;
        $params = [
            'index' => 'goods',
            'type' => '_doc',
            'id' => $info->id,
            'body' => [
                'goods_name' => $goods_name,
            ]
        ];
        $es->addIndex($params);
        $data = [
            'code' => 1,
            'msg' => null,
            'data' => []
        ];
        return $data;
    }

    public static function goodsUpdate($row, $post)
    {
        if ($post['is_specifica'] == 0) {
            unset($post['skus']);
            $sku = $post['sku'];
            unset($post['sku']);
            unset($post['file']);
            Goods::where('id', $row['id'])->update($post);
            $sku['attr_values'] = $post['goods_name'];
            $data = GoodsSku::where('goods_id', $row['id'])->update($sku);
            return $data;
        } else {
            unset($post['skus']);


        }
    }

    /**
     * Author:Zhongyuan Lu
     * 恢复商品
     * @param $id
     * @return array
     */
    public static function restore($id)
    {
        $goods = Goods::onlyTrashed()->find($id);
        $goods->restore();
        $data = [
            'code' => 1,
            'msg' => '恢复成功',
            'data' => []
        ];
        return $data;
    }

    /**
     * Author:Zhongyuan Lu
     * 真实删除
     * @param $id
     * @return array
     */
    public static function forceDelete($id)
    {
        Goods::destroy($id, true);
        $data = [
            'code' => 1,
            'msg' => '删除成功',
            'data' => []
        ];
        return $data;
    }

    public static function getTreeCate()
    {
        $res = GoodsCate::select()->toArray();
        $data = getTree($res);
        $data = [
            'code' => 1,
            'msg' => null,
            'data' => $data
        ];
        return $data;
    }

    public static function getRuleList($id)
    {
        if (empty($id)) {
            $data = GoodsSpecifica::select();
            if ($data) {
                $data = $data->toArray();
            } else {
                $data = [];
            }
        } else {
            $data[] = GoodsSpecifica::find($id)->toArray();
        }

        return $data;
    }

    public static function getSku($id)
    {
        $model = new Goods();
        $data = $model->where('id', $id)->with('sku')->find()->toArray();
        return $data;
    }

    /**
     * Author:Zhongyuan Lu
     * 获取商品详情
     * @param $goods_id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getGoodsDetail($goods_id, $uid = 0)
    {
        if (empty($goods_id) || $goods_id < 1) {
            return self::fail([], 400, '参数错误');
        }
        $field = [
            'id',
            'goods_name',
            'goods_desc',
            'image',
            'goods_carousel',
            'goods_details',
            'goods_price',
            'original_price',
            'vip_price',
            'goods_ficti',
            'goods_stock',
            'keyword',
            'integral'
        ];
        $goods = Goods::with(['sku'])->field($field)->find($goods_id);
        $sku_ids = GoodsSku::where('goods_id',$goods_id)->column('id');
        $orderIds = OrderGoodsInfo::where('goods_sku_id', 'in',$sku_ids)->column('order_id');
        $commentCount = GoodsComment::where('uid',$uid)->where('oid', 'in', $orderIds)->count();
        $goods && $goods = $goods->toArray();
        //是否收藏
        $goods['is_collection'] = Cache::get("one:ea_user_collection:uid{$uid}:product_id{$goods_id}") ? 1 : 0;
        //轮播图
        $goods['goods_carousel'] = explode('|', $goods['goods_carousel']);;
        $goods['comment_count'] = $commentCount;

        if (empty($goods['sku'][0]['attr_values'])) {
            //单规格
            $goods['type'] = 0;
        } else {
            //多规格
            $goods['type'] = 1;
            $data = [];

            foreach ($goods['sku'] as &$v) {
                $i = 0;
                $v['attr_values'] = json_decode($v['attr_values'], true);
                foreach ($v['attr_values'] as $key => $value) {
                    $goods['attr'][$i]['attr_name'] = $key;
                    $goods['attr_name'][] = $key;
                    $goods['attr'][$i]['attr_value'][] = $value;
                    $goods['attr_name'] = array_unique($goods['attr_name']);
                    $goods['attr'][$i]['attr_value'] = array_unique($goods['attr'][$i]['attr_value']);
                    $i++;
                }
                sort($v['attr_values']);
                $key = implode('|', $v['attr_values']);
                $data[$key] = $v;
            }
            unset($v);
            $goods['sku'] = $data;
        }

        if ($uid) {
            Event::listen('UserAction', 'app\listener\UserActionListener');
            //type 1 浏览  2 搜索
            event('UserAction', ['uid' => $uid, 'type' => 1, 'keyword' => $goods['keyword'], 'price' => $goods['goods_price']]);
        }
        unset($goods['keyword']);
        return self::success('获取成功', $goods);
    }

    /**
     * 创建es商品索引
     * Author:YangXinPeng
     * @return array
     */
    public static function addGoodIndex()
    {
        $indexName = "goods";
        $params = [
            'index' => $indexName,
            'body' => [
                'settings' => [
                    'number_of_shards' => 3,
                    'number_of_replicas' => 2
                ],
                'mappings' => [
                    '_source' => [
                        'enabled' => true
                    ],
                    'properties' => [
                        'goods_name' => [
                            'type' => 'text',
                            "analyzer" => "ik_max_word",
                            "search_analyzer" => "ik_max_word"
                        ],
                    ]
                ]
            ]
        ];
        $es = new Es();
        $res = $es->createIndex($params);
        return $res;
    }

    /**
     * Author:YangXinPeng
     * 商品名称es搜索
     * @param $keyword
     * @return array
     */
    public static function search($keyword, $uid = 0)
    {
        $es = new Es();
        $params = [
            'index' => 'goods',
            'type' => '_doc',
            'body' => [
                'query' => [
                    'match' => [
                        'goods_name' => $keyword
                    ]
                ],
                'highlight' => [
                    'pre_tags' => ["<em style='color:red'>"],
                    'post_tags' => ["</em>"],
                    'fields' => [
                        "goods_name" => new \stdClass()
                    ]
                ]
            ]
        ];
        $result = [];
        $arr = [];
        $res = $es->match($params);
        $data = $res['hits']['hits'];
        foreach ($data as $key=>$value) {
            $arr[$key]['goodId'] = $value['_id'];
            $arr[$key]['goods_name'] = $value['highlight']['goods_name'];
        }
        foreach ($arr as $v) {
            $good = Goods::find($v['goodId']);
            $good && $good = $good->toArray();
            $good['goods_name'] = $v['goods_name'][0];
            $result[] = $good;
        }
//        if ($uid) {
//            Event::listen('UserAction', 'app\listener\UserActionListener');
//            //type 1 浏览  2 搜索
//            event('UserAction',['uid' => $uid, 'type' => 2, 'keyword' => $goods['keyword'], 'price' => $goods['goods_price']]);
//        }

        return $result;
    }


    /**
     * Author:Yingbo Sun
     * 随机返回热门推荐
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getHotRecommend()
    {
        $count = Goods::where('is_hot', '1')->count();
        $size = intval($count / config('setting.recommend_limit'));
        $page = mt_rand(1, $size);
        $data = Goods::where('is_hot', '1')
//            ->limit($page, config('setting.recommend_limit'))
            ->field(['id', 'goods_name', 'image', 'goods_price', 'original_price'])
            ->select();
        $data && $data = $data->toArray();
        return self::success('获取成功', $data);
    }

    /**
     * Author:Zhongyuan Lu
     * 分片上传
     * @param $params
     * @param $file
     * @return int[]
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public static function bigUpload($params, $file)
    {
        $status = 1;
        //获得上传文件
        $data = file_get_contents($file['tmp_name']);
        $redis = Cache::store('redis');
        $redis->select(9);

        //获得文件名
        $filename = "{$params['fileName']}.{$params['fileExt']}";

        //判断redis中对应的文件是否有值
        $files = $redis->get("xs1:cos:{$filename}:resources") ?:[];
        if (empty($files))
        {
            $redis->set("xs1:cos:{$filename}:resources",json_encode([]),600);
        }

        //获得redis中上传的分片数据
        $files = json_decode($redis->get("xs1:cos:{$filename}:resources"),true);
        $cos = new Cos();

        //分片上传
        $arr = $cos->bigCoss($data,$params,$filename);
        //将上传后的数据放入redis对应的数据中
        array_push($files,json_encode($arr));
        $redis->set("xs1:cos:{$filename}:resources",json_encode($files));

        //最后一个分片
        if ($params['totalPage'] == $params['page']) {
            $status = 2;
            $arr = json_decode($redis->get("xs1:cos:{$filename}:resources"),true);
            $resources = [];
            foreach ($arr as $value){
                $resources[] = json_decode($value,true);
            }
            //将分片数据合并为最终文件
            $cos->complete($resources,$filename);
            $redis->del("xs1:cos:{$filename}:resources");
            $res = ['status' => $status];
            return $res;
        }
        $res = ['status' => $status];
        return $res;
    }

    /**
     * Author:Zhongyuan Lu
     * 根据商品id获取sku商品
     * @param $goods_id
     * @param int $type
     * @param int $page
     * @param int $limit
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getGoodsSku($goods_id, $type = 1, $page = 1, $limit = 10)
    {
        if ($type == 1) {
            $list = GoodsSku::find($goods_id);
            $list && $list = $list->toArray();
            return $list;
        }

        $list = GoodsSku::where('goods_id',$goods_id)->paginate($limit);
        $list && $list = $list->toArray();
        foreach ($list['data'] as &$v) {
            $v['attr_values'] = implode('|',json_decode($v['attr_values'],true));
        }
        unset($v);

        return [
            'code' => 0,
            'msg' => '',
            'count' => $list['total'],
            'data' => $list['data'],
        ];
    }

    /**
     * Author:Zhongyuan Lu
     * 获取sku详情
     * @param $skuId
     * @return array|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getSkuDetail($skuId)
    {
        $data = GoodsSku::find($skuId);
        $data && $data = $data->toArray();
        return $data;
    }

    /**
     * Author:Zhongyuan Lu
     * 根据skuid查询对应的图片
     * @param $sku_id
     * @return array
     */
    public static function getSkuImages($sku_id)
    {
        $data = GoodsSku::where('id','in',$sku_id)->column('sku_image');
        return $data;
    }

    /**
     * Author:Yingbo Sun
     * 分类商品列表
     * @param $cateId
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function cateGoodsList($cateId)
    {
        if (empty($cateId)){
            return self::fail('参数错误');
        }
        $redis = Cache::store('redis');
        $redis->select(11);
        $bool = $redis->has("cateGoodsList:{$cateId}");
        if ($bool){
            $data = $redis->get("cateGoodsList:{$cateId}");
        }else{
            $field = ['id','goods_name','image','goods_price','vip_price'];
            $data = Goods::where('goods_type',$cateId)->field($field)->select();
            $data && $data = $data->toArray();
            if (empty($data)){
                $redis->set("cateGoodsList:{$cateId}",$data,300);
            }
            $redis->set("cateGoodsList:{$cateId}",$data);
        }

        return self::success('获取成功',$data);
    }

    //实时更新商品销量
    public static function liveGoodsNumberUp($num,$goodsId)
    {
        if (empty($num) || empty($goodsId)){
            return self::fail('参数错误');
        }
        $redis = Cache::store('redis');
        $redis->select(13);

    }

    /**
     * Author:Yingbo Sun
     * 积分兑换商品列表
     * @param int $page
     * @param int $limit
     * @param array $where
     * @return array
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getExchangeGoodsList($page = 0, $limit = 0, $where = [])
    {
        if (empty($page) && empty($limit) && empty($where)){

            $redis = Cache::store('redis');
            $redis->select(15);
            $bool = $redis->has("getExchangeGoodsList");
            if ($bool){
                $list = $redis->get("getExchangeGoodsList");
            }else{
                $where[] = ['is_status',"=",'1'];
                $list = GoodsExchange::where($where)
                    ->with(["getGoodsInfo","getGoodsSkuInfo"])
                    ->select();
                $list && $list = $list->toArray();
                if (empty($list)){
                    $redis->set('getExchangeGoodsList',$list,300);
                }
                $redis->set("getExchangeGoodsList",$list);
            }
            return self::success('获取成功',$list);
        }else{
            $count = GoodsExchange::where($where)
                ->count();
            $list = GoodsExchange::where($where)
                ->with(["getGoodsInfo","getGoodsSkuInfo"])
                ->page($page, $limit)
                ->order('id','desc')
                ->select();
            $data = [
                'code' => 0,
                'msg' => '',
                'count' => $count,
                'data' => $list,
            ];
            return $data;
        }
    }

    /**
     * Author:Yingbo Sun
     * 详情
     * @param $id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getExchangeGoodsDetails($id)
    {
        if (empty($id)){
            return  self::fail('参数错误');
        }
        $where[] = ['is_status',"=",'1'];
        $where[] = ['id','=',$id];
        $list = GoodsExchange::where($where)
            ->with(["getGoodsInfo","getGoodsSkuInfo"])
            ->select();
        $list && $list = $list->toArray();
        return self::success('获取成功',$list);
    }

    /**
     * Author:Yingbo Sun
     * 获取商品地址
     * @param $skuId
     * @return array|mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function goodsAddress($skuId)
    {
        if (empty($skuId)) {
            return self::fail('参数错误');
        }

        $sku = GoodsSku::where('id', $skuId)->find();
        $address = Goods::where('id',$sku->goods_id)->value('goods_address');
        return $address;
    }



    public static function getGoodDetail($goods_id, $sku_id,$uid = 0)
    {
        if (empty($goods_id) || $goods_id < 1) {
            return self::fail([], 400, '参数错误');
        }
        $field = [
            'id',
            'goods_name',
            'goods_desc',
            'image',
            'goods_carousel',
            'goods_details',
            'goods_price',
            'original_price',
            'vip_price',
            'goods_ficti',
            'goods_stock',
            'keyword',
            'integral'
        ];
        $goods = Goods::with(['sku'])->field($field)->find($goods_id);
        $commentCount = GoodsComment::where('goods_id', $goods_id)->count();
        $goods && $goods = $goods->toArray();
        //是否收藏
        $goods['is_collection'] = Cache::get("one:ea_user_collection:uid{$uid}:product_id{$goods_id}") ? 1 : 0;
        //轮播图
        $goods['goods_carousel'] = explode('|', $goods['goods_carousel']);;
        $goods['comment_count'] = $commentCount;

        if (empty($goods['sku'][0]['attr_values'])) {
            //单规格
            $goods['type'] = 0;
        } else {
            //多规格
            $goods['type'] = 1;
            $data = [];

            foreach ($goods['sku'] as &$v) {
                if ($v['id'] == $sku_id){
                    $i = 0;
                    $v['attr_values'] = json_decode($v['attr_values'], true);
                    foreach ($v['attr_values'] as $key => $value) {
                        $goods['attr'][$i]['attr_name'] = $key;
                        $goods['attr_name'][] = $key;
                        $goods['attr'][$i]['attr_value'][] = $value;
                        $goods['attr_name'] = array_unique($goods['attr_name']);
                        $goods['attr'][$i]['attr_value'] = array_unique($goods['attr'][$i]['attr_value']);
                        $i++;
                    }
                    sort($v['attr_values']);
                    $key = implode('|', $v['attr_values']);
                    $data[$key] = $v;
                }
            }
            unset($v);
            $goods['sku'] = $data;
        }

        if ($uid) {
            Event::listen('UserAction', 'app\listener\UserActionListener');
            //type 1 浏览  2 搜索
            event('UserAction', ['uid' => $uid, 'type' => 1, 'keyword' => $goods['keyword'], 'price' => $goods['goods_price']]);
        }
        unset($goods['keyword']);
        return self::success('获取成功', $goods);
    }
}















